package com.cta.service.report.impl;

import java.sql.SQLException;

import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cta.dao.report.MasterDataDao;
import com.cta.dao.report.impl.JDBCDao;
import com.cta.entity.MasterData;
import com.cta.service.report.MasterDataService;
import com.cta.view.model.DurationLock;

@Service("masterDataService")
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MasterDataServiceImpl implements MasterDataService {

	private static final String slaveTable = "cdr_slave_data_";
	private static final String TABLE_NAME = "CREATE TABLE %s (" + "uid uuid NOT NULL,"
			+ "def_trunk_no character varying(255)," + "def_pbx_no character varying(255) NOT NULL,"
			+ "def_start_time time without time zone NOT NULL,"
			+ "def_start_date timestamp without time zone NOT NULL,"
			+ "def_end_date timestamp without time zone NOT NULL," + "def_duration bigint NOT NULL,"
			+ "def_user_id bigint," + "def_telco character varying(255)," + "def_author_code character varying(255),"
			+ "def_dialed_number character varying(25) NOT NULL," + "def_calling_number character varying(255),"
			+ "def_destination character varying(255)," + "def_price double precision NOT NULL DEFAULT 0,"
			+ "def_discount character varying(255)," + "def_reg_date timestamp without time zone NOT NULL,"
			+ "code_dialed character varying(255)," + "code_used character varying(255),"
			+ "acct_code character varying(255)," + "attd_console character varying(255),"
			+ "auth_code character varying(255)," + "bandwith character varying(255)," + "bcc character varying(255),"
			+ "calling_num character varying(255)," + "calltype character varying(255),"
			+ "clg_num_in_tac character varying(255)," + "\"return\" character varying(255),"
			+ "condition_code character varying(255)," + "condition_code_overrides character varying(255),"
			+ "contact_uri character varying(255)," + "country_from character varying(255),"
			+ "country_to character varying(255)," + "date character varying(255),"
			+ "dialed_num character varying(255)," + "duration character varying(255),"
			+ "feat_flag character varying(255)," + "format_code character varying(255),"
			+ "form_uri character varying(255)," + "in_crt_id character varying(255),"
			+ "in_trk_code character varying(255)," + "ins character varying(255),"
			+ "internal_codec character varying(255)," + "isdn_cc character varying(255),"
			+ "isdn_cc_ppm character varying(255)," + "ixc_code character varying(255),"
			+ "location_from character varying(255)," + "location_to character varying(255),"
			+ "ma_uui character varying(255)," + "node_num character varying(255),"
			+ "out_crt_id character varying(255)," + "tsc_ct character varying(255)," + "ppm character varying(255),"
			+ "request_uri character varying(255)," + "res_flag character varying(255),"
			+ "sec_dur character varying(255)," + "seq_num character varying(255),"
			+ "start_date character varying(255)," + "start_time character varying(255),"
			+ "\"time\" character varying(255)," + "timezone_from character varying(255),"
			+ "timezone_to character varying(255)," + "to_uri character varying(255),"
			+ "tsc_flag character varying(255)," + "trunk_codec character varying(255),"
			+ "ucid character varying(255)," + "vdn character varying(255),"
			+ "CONSTRAINT %s_pkey PRIMARY KEY (uid ) )";

	@Autowired
	private MasterDataDao masterDataDao;

	@Autowired
	private JDBCDao abstractJdbcDao;

	@Transactional(readOnly = false)
	public DurationLock createTable(LocalDate start) throws SQLException {

		LocalDate startDay = start.dayOfMonth().withMinimumValue();
		LocalDate endDay = start.dayOfMonth().withMaximumValue();
		MasterData ms = new MasterData();
		ms.setFromDate(startDay.toDate());
		ms.setToDate(endDay.toDate());

		MasterData masterData = masterDataDao.lookup(ms.getFromDate(), ms.getToDate());
		if (masterData == null) {
			long total = masterDataDao.total() + 1;
			ms.setTableName(slaveTable + total);
			// masterDataDao.save(ms);
			abstractJdbcDao
					.insert("INSERT INTO cta_master_data(id, date_from, table_name, date_to) VALUES (nextval ('cta_master_data_seq'), ?, ?, ?);",
							new Object[] {ms.getFromDate(), ms.getTableName(), ms.getToDate()});
			// create table
			abstractJdbcDao.execute(String.format(TABLE_NAME, slaveTable + total, slaveTable + total).replaceAll("\"",
					""));

			masterData = ms;
			masterData.setTableName(slaveTable + total);
		}
		DurationLock lock = new DurationLock(startDay, endDay, masterData.getTableName());
		return lock;
	}

	@Transactional(readOnly = false)
	public void insertData(Object[] data) throws Exception {
		abstractJdbcDao.insert((String) data[0], (Object[]) data[1]);
	}
}
